import { ipcRenderer } from "electron";
import { IndexedDBHelper } from "./IndexedDBHelper";


function createSingletonDBHelper<T extends { [key: string]: any; }>(dbName: string, version: number): () => IndexedDBHelper<T> {
  let instance: IndexedDBHelper<T> | null = null;
  return () => {
    if (!instance) {
      instance = new IndexedDBHelper<T>(dbName, version);
    }
    return instance;
  };
}

// 使用工厂创建单例
export const getMemoDatabaseHelper = createSingletonDBHelper<any>("MemoDatabase", 1);
export const getDateListDatabaseHelper = createSingletonDBHelper<any>("DateListDatabase", 1);


export function formatTime(timestamp: number): string {
  const date = new Date(timestamp);

  const year = date.getFullYear();
  const month = String(date.getMonth() + 1).padStart(2, "0"); // 月份从0开始
  const day = String(date.getDate()).padStart(2, "0");

  const hours = String(date.getHours()).padStart(2, "0");
  const minutes = String(date.getMinutes()).padStart(2, "0");
  const seconds = String(date.getSeconds()).padStart(2, "0");

  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
}

export function formatDate(timestamp: number): string {
    const date = new Date(timestamp);
  
    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, "0"); // 月份从0开始
    const day = String(date.getDate()).padStart(2, "0");  
    return `${year}-${month}-${day}`;
  }

export function getRandomLowercaseString(length: number = 5): string {
  const chars = "abcdefghijklmnopqrstuvwxyz";
  let result = "";
  for (let i = 0; i < length; i++) {
    result += chars[Math.floor(Math.random() * chars.length)];
  }
  return result;
}

export function generateUUID(): string {
  return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
    const r = (Math.random() * 16) | 0;
    const v = c === "x" ? r : (r & 0x3) | 0x8;
    return v.toString(16);
  });
}

/**
 * 生成基于时间戳的五位唯一流水号
 * @returns 五位数字字符串
 */
export function generateSerialNumber(): string {
  const timestamp = Date.now();
  const randomNum = Math.floor(Math.random() * 1000);
  const serial = (timestamp % 100000) + randomNum % 100000;
  return serial.toString().padStart(5, '0');
}



export const backupIndexedDB = async () => {
  try {
    // 通过API获取所有数据
    const response = await fetch('http://localhost:32068/api/storage');
    const data = await response.json();
    
    if (data.code !== 200) {
      throw new Error(data.error || '获取数据失败');
    }

    // 构建导出数据
    const content = JSON.stringify(data.data, null, 2);

    // 显示保存对话框
    const { filePath } = await ipcRenderer.invoke("showSaveDialog", {
      title: "保存备份文件",
      defaultPath: `memory_${formatDate(Date.now())}.json`,
      filters: [
        { name: "JSON Files", extensions: ["json"] },
        { name: "All Files", extensions: ["*"] },
      ],
    });

    if (filePath) {
      // 写入文件
      await ipcRenderer.invoke("writeFile", { filePath, content });
      alert("备份导出成功");
    }
  } catch (error: any) {
    console.error("备份导出失败:", error);
    alert(`备份导出失败: ${error.message}`);
  }
};

export const importDatabase = async () => {
  try {
    // 显示打开文件对话框
    const { filePaths } = await ipcRenderer.invoke("showOpenDialog", {
      title: "选择备份文件",
      filters: [
        { name: "JSON Files", extensions: ["json"] },
        { name: "All Files", extensions: ["*"] },
      ],
    });

    if (!filePaths || !filePaths.length) {
      alert("未选择文件");
      return;
    }

    const filePath = filePaths[0];

    // 读取文件内容
    const content = await ipcRenderer.invoke("readFile", { filePath });

    // 解析JSON数据
    const data = JSON.parse(content);

    // 通过API还原数据
    const response = await fetch('http://localhost:32068/api/storage/restore', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(data),
    });

    const result = await response.json();
    
    if (result.code !== 200) {
      throw new Error(result.error || '数据还原失败');
    }

    alert("数据库还原成功");

    ipcRenderer.invoke("relaunch")
    // window.location.reload(); // 暂时注释以避免强制刷新导致上下文丢失
  } catch (error: any) {
    console.error("数据库还原失败:", error);
    alert(`数据库还原失败: ${error.message}`);
  }
};

export  const debounce = <T extends (...args: any[]) => any>(func: T, delay: number): (...args: Parameters<T>) => void => {
  let timeoutId: ReturnType<typeof setTimeout> | undefined;

  return (...args: Parameters<T>) => {
    if (timeoutId) {
      clearTimeout(timeoutId);
    }

    timeoutId = setTimeout(() => {
      func(...args);
    }, delay);
  }
}

export  enum NoteType {
  Document = 'Document', // 文档
  Folder = 'Folder', // 文件夹
}


interface TreeNode {
  id: string;
  parentId: string | null;
  isFolder: boolean;
  title: string;
  content: string;
  created: string;
  updated: string;
  titleIsEditing: boolean;
  key?: string; // 为 Ant Design Tree 添加的 key 属性
  children?: TreeNode[];
}

/**
 * 将扁平数组转换为树形结构
 * @param items 扁平数组
 * @param parentId 父节点ID，顶层节点为null
 * @returns 树形结构数组
 */
 export function buildTree(items: TreeNode[], parentId: string | null =  null): TreeNode[] {
  const tree: TreeNode[] = [];
  
  // 找出所有父节点为指定parentId的节点
  const children = items.filter(item => item.parentId == parentId);
  
  // 递归构建子树
  for (const child of children) {
    const node: TreeNode = {
      ...child,
      key: child.id, // Ant Design Tree需要key属性
      title: child.title,
      children: buildTree(items, child.id)
    };
    
    // 如果是文件夹且有子节点，则保留children，否则设为undefined
    if (!node.isFolder || node?.children?.length === 0) {
      delete node.children;
    }
    
    tree.push(node);
  }
  
  return tree;
}
